import datetime
import re

from django.conf import settings
from rest_framework.response import Response

from app.models import WxUser, get_user_mobile_list, UserAddress
from jiaozi.base_view import JwtListAPIView, JwtListCreateAPIView, GenericAPIView
from jiaozi.utils import get_user_id, make_wx_pay_order, get_client_ip, APIResponse, MmFilter
from money.models import PayRecord
from vip.serializers import *


class VipLevelListView(JwtListAPIView):
    """
    VIP 等级获取
    """
    authentication_classes = ()
    permission_classes = ()
    pagination_class = None
    serializer_class = VipLevelSerializer
    queryset = VipLevel.objects.all()
    search_fields = ['level_name']


class VipSalesListView(JwtListAPIView):
    """
    在售的 VIP 类型，包含价格信息
    """
    permission_classes = ()
    queryset = None
    pagination_class = None
    serializer_class = VipSalesSerializer
    search_fields = ['vip_level__level_name']

    def get_queryset(self):
        queryset = VipSales.objects.filter(is_show=True).order_by('pk')
        return queryset

    def list(self, request, *args, **kwargs):
        user_id = get_user_id(self)
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        raw_data = serializer.data
        res_data = list()
        level_dict = dict()
        for row in raw_data:
            level_id = row['vip_level']['id']
            row['rules'] = re.split(r'\s+', row.get('rules', ''))
            if level_id not in level_dict:
                level_dict[level_id] = 0
                row['has_bought'] = False
                if user_id:
                    if VipSalesOrder.objects.filter(user_id=user_id, vip_sales=row['id'], is_payed=True).count() > 0:
                        row['has_bought'] = True
                res_data.append(row)
        return APIResponse(data=res_data)


class BuyVipFilter(MmFilter):
    class Meta:
        model = VipSalesOrder
        fields = {
            # 'is_payed': ['exact'],
            'vip_sales': ['exact'],
        }


class BuyVipView(JwtListCreateAPIView):
    """
    get:

        查询 VIP 购买记录，用户只能查询自己的购买记录

    post:

         用户发起 VIP 购买，用户同一时间段只可以购买一个相同的 VIP。

    """
    queryset = None
    serializer_class = VipSalesOrderSerializer
    filterset_class = BuyVipFilter
    pagination_class = None

    def get_queryset(self):
        user_id = get_user_id(self)
        if user_id:
            queryset = VipSalesOrder.objects.filter(user_id=user_id).filter(is_payed=True)
        else:
            queryset = VipSalesOrder.objects.none()
        return queryset

    def create(self, request, *args, **kwargs):
        vip_sales_id = request.data.get('vip_sales')
        if not vip_sales_id:
            return APIResponse(status=400, message='请提供vip_sales')

        new_data = dict()
        new_data['vip_sales_id'] = vip_sales_id

        # 添加默认值 user 为提交的用户
        user_id = get_user_id(self)
        new_data['user_id'] = user_id

        openid = WxUser.objects.get(pk=user_id).openid
        if not openid:
            return APIResponse(status=200, code=400, message='账号未登录')

        # 判断用户之前是否买过会员
        pre_vip_orders = VipSalesOrder.objects.filter(
            user_id=user_id,
            is_payed=True,
            vip_sales_id=vip_sales_id,
        )
        if pre_vip_orders.exists():
            return APIResponse(status=200, code=400, message='请勿重复购买')

        # 查询会员售卖的价格
        current_vip_sales = VipSales.objects.get(pk=vip_sales_id)
        price = current_vip_sales.price_show
        new_data['price_initial'] = float(price)
        new_data['price_payed'] = float(price)
        # 写入订单
        vip_sales_order = VipSalesOrder.objects.create(**new_data)

        # 构建支付订单
        total_fee = str(int(float(price)*100))

        pay_record = PayRecord.objects.create(
            sales_order_id=vip_sales_order.pk,
            pay_type=1,
            user_id=user_id,
            openid=openid,
            body='购买VIP',
            total_fee=total_fee,
            pay_time=datetime.datetime.now()
        )
        vip_sales_order.pay_record = pay_record
        vip_sales_order.save()
        # 发起支付
        out_trade_no = pay_record.out_trade_no
        wx_params = make_wx_pay_order(
            openid,
            out_trade_no,
            pay_record.total_fee,
            body=pay_record.body,
            client_ip=get_client_ip(request)
        )

        data = {
            'pay_info': wx_params,
            'out_trade_no': out_trade_no,
            'price': price,
        }
        return APIResponse(data=data)

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        raw_data = serializer.data
        for row in raw_data:
            row['vip_sales'].pop('body_cn')
            row['vip_sales'].pop('body_en')
            vip_level_id = row['vip_sales']['vip_level']
            row['vip_sales']['vip_level'] = model_data_from_cache(VipLevel, vip_level_id)
        return APIResponse(data=raw_data)


class NotBuyView(GenericAPIView):
    """
    本次还没购买的用户
    """
    authentication_classes = ()
    permission_classes = ()
    pagination_class = None
    filter_backends = ()
    queryset = VipSalesOrder.objects.none()

    def get(self, request):
        from product.views import get_user_can_buy_amount
        data = []
        if request.GET.get('key', '') == 'jiaozi2021':
            current_time = datetime.datetime.now()
            vip_sales_orders = VipSalesOrder.objects.filter(
                is_payed=True,
                vip_sales__vip_start__lte=current_time,
                vip_sales__vip_end__gte=current_time,
            ).values('user_id', 'vip_sales__vip_level_id', 'vip_sales__vip_level__level_name')

            user_list = list()
            user_vip_dict = dict()

            for vip_sales_order in vip_sales_orders:
                user_id = vip_sales_order['user_id']
                if user_id not in user_vip_dict:
                    user_vip_dict[user_id] = list()
                user_vip_dict[user_id].append(vip_sales_order['vip_sales__vip_level__level_name'])
                can_buy_amount, has_bought_product_ids = get_user_can_buy_amount(user_id)
                for vip_level, amount in can_buy_amount.items():
                    if amount > 0:
                        user_list.append(user_id)

            user_list = list(set(user_list))

            user_mobile_dict = dict(WxUser.objects.filter(
                pk__in=user_list
            ).values_list('id', 'mobile').order_by('pk'))

            user_name_dict = dict(UserAddress.objects.filter(
                user_id__in=user_list
            ).values_list('user_id', 'name').order_by('pk'))

            data = list()
            for user_id, mobile in user_mobile_dict.items():
                if mobile not in settings.TEST_MOBILE:
                    data.append(
                        {
                            'id': user_id,
                            'name': user_name_dict.get(user_id, ''),
                            'mobile': int(mobile),
                            'vips': user_vip_dict.get(user_id, [])
                        }
                    )
        return Response(data=data)
